package cn.shutdown.demo.jvm;

/**
 *
 * 测试变量的GC结果
 * 执行时增加jvm参数  -XX:+PrintGC
 * @author domino
 * @date 2021/5/17
 */
public class TestLocalVariable {

    /**
     * 有引用指向变量不会被回收
     */
    public void localVarGc1() {
        byte[] a = new byte[6 * 1024 * 1024];
        System.gc();
    }

    /**
     * 无引用指向变量被回收
     */
    public void localVarGc2() {
        byte[] a = new byte[6 * 1024 * 1024];
        a = null;
        System.gc();
    }

    /**
     * 虽然变量超过作用域，但是变量仍存在于局部变量表中，并且也指向数组，所以不会被立即回收
     */
    public void localVarGc3() {
        {
            byte[] a = new byte[6 * 1024 * 1024];
        }
        System.gc();
    }

    /**
     * a变量超过了作用域，a变量失效，新建变量c，使用了a变量的字，a变量被销毁，垃圾回收可以正常回收数组
     */
    public void localVarGc4() {
        {
            byte[] a = new byte[6 * 1024 * 1024];
        }
        int c = 10;
        System.gc();
    }

    /**
     * 调用 localVarGc1 方法以后，localVarGc1的栈帧被销毁，栈帧中的局部变量被销毁，所以可以正常垃圾回收
     */
    public void localVarGc5() {
        localVarGc1();
        System.gc();
    }

    public static void main(String[] args) {
        TestLocalVariable t1 = new TestLocalVariable();
        t1.localVarGc1();
        System.out.println("----------------------");
        t1.localVarGc2();
        System.out.println("----------------------");
        t1.localVarGc3();
        System.out.println("----------------------");
        t1.localVarGc4();
        System.out.println("----------------------");
        t1.localVarGc5();
    }
}
